package com.cskaoyan.javase.oop3._2inner._5anonymous._2notice;

import com.cskaoyan.javase.oop3._0abstract._1basic.Test;

/**
 * 匿名内部类实际上就是更简单的局部内部类（直接获取了对象）
 * 所以局部内部类的使用场景，可以直接套用过来。
 * 实际开发中,匿名内部类基本取代局部内部类的使用场景.
 *
 * 匿名内部类经常使用在以下两个场景中：
 * 方法需要返回一个对象，返回值类型是引用数据类型时。
 * 方法需要返回一个对象时，可以在方法的局部位置写一个 基于X类或X接口的匿名内部类对象 ，然后直接作为返回值返回给外界。
 * 方法需要传入一个对象，形参数据类型是引用数据类型时。
 * 方法需要传入一个对象实参时，可以在调用方法的实参位置填入一个 基于X类或X接口的匿名内部类对象，就将它作为一个实参传给方法使用。
 *
 * 使用匿名内部类的优点：
 * 绝对对外界隐藏，封装。
 * 比起局部内部类，它更方便简洁了。所以实际开发中，匿名内部类基本取代了局部内部类的作用。
 * 缺点：
 *
 * 这个对象是一次性的。
 * 总之，酌情使用匿名内部类对象，可以简化代码书写，方便省事。但不要为了使用而使用，假如存在多个场景都需要一个子类对象，那还是直接创建一个子类出来好了。
 *
 * @since 11:41
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        method().test();
        // 传统调用方法
        method(new IAImpl());
        class IAImpl implements IA {
            @Override
            public void test() {
                System.out.println("局部内部类实现!");
            }
        }
        // 局部内部类的做法
        method(new IAImpl());
        // 匿名内部类的做法
        method(new IA() {
            @Override
            public void test() {
                System.out.println("匿名内部类");
            }
        });
    }

    // 该方法需要传入一个接口的子类对象
    public static void method(IA ia) {
        ia.test();
    }

    // 该方法需要返回一个接口IA的子类对象
    public static IA method() {
        // return new IAImpl();
        // 局部内部类去实现
        /*class IAImpl implements IA {
            @Override
            public void test() {
                System.out.println("局部内部类实现!");
            }
        }
        return new IAImpl();*/
        return new IA() {
            @Override
            public void test() {
                System.out.println("我是匿名内部类,我更高级,我是更简洁的!");
            }
        };
    }
}

// 传统做法
class IAImpl implements IA {
    @Override
    public void test() {
        System.out.println("传统方法!");
    }
}

interface IA {
    void test();
}